-- Function: generar_asiento_apertura(character varying, timestamp without time zone)

-- DROP FUNCTION generar_asiento_apertura(character varying, timestamp without time zone);

CREATE OR REPLACE FUNCTION generar_asiento_apertura(character varying, timestamp without time zone)
  RETURNS integer AS
$BODY$

DECLARE
pCodAmbSuc	ALIAS FOR $1;
pFecha       	ALIAS FOR $2;
cAsiento        REFCURSOR;
vIdCommCierre	 INTEGER;
vIdCtb		 INTEGER;
vCodCtb		 VARCHAR(20);
vNombreCtb       VARCHAR(100);
vSigno		 INTEGER;
vImpo		 NUMERIC(16,2);
vAsientoAperturaTipoCom	 VARCHAR(4);
vNroXml         INTEGER;

BEGIN

-- Primero verifico que esten todos los parametros que requiere la apertura contable.
select ctbcfg.asientoaperturatipocom into vAsientoAperturaTipoCom
from ctbcfg
join com on ctbcfg.asientoaperturatipocom = com.tipo;

IF vAsientoAperturaTipoCom IS NULL THEN 
  RAISE EXCEPTION 'Primero debe configurar en la opcion Parametros Contables el comprobante de Asiento de Apertura Contable';
END IF;

-- Busco el ultimo comprobante de cierre de cuentas patrimoniales grabado en la sucursal en que estoy posicionado
-- con fecha menor a la del asiento de apertura a generar.
select comm.id into vIdCommCierre
from comm
where comm.generadopor = 'XML:CCP' and
comm.fecha < pFecha and
comm.codambsuc = pCodAmbSuc
order by fecha desc
limit 1;

IF vIdCommCierre IS NULL 
  THEN RAISE EXCEPTION 'No existe un asiento de cierre en la sucursal que esta posicionado y con fecha menor a la apertura que desea generar.';
END IF;

-- Generacion del xml
-- Obtencion del numero de importacion.
vNroXml:= ( SELECT NEXTVAL('importacion.sec_next_nroxml') );
perform importacion.impxml_add(vNroXml, '<Movimientos>');

-- 1) Recupero los pases del asiento del vIdCommCierre.
open cAsiento FOR
(
SELECT ctb.id as idctb, ctb.cod as codctb, ctb.nombre as nombrectb, 
-1 * commov.signo as signo, commov.impo as impo
FROM commov
JOIN ctb on commov.idctb = ctb.id
WHERE commov.idcomm = vIdCommCierre
ORDER by 4 desc, 2
);

-- Aqui se genera el comprobante.
perform importacion.impxml_add(vNroXml, '<Comprobante TipoCom = ''' || vAsientoAperturaTipoCom || '''>');
perform importacion.impxml_add(vNroXml, '<Encabezado>');
perform importacion.impxml_add(vNroXml, '<Fecha>' || to_char(cast(pFecha as date), 'DD/MM/YYYY') || '</Fecha>'); 
perform importacion.impxml_add(vNroXml, '<Detalle>' || 'Asiento de Apertura' || '</Detalle>'); 
perform importacion.impxml_add(vNroXml, '<GeneradoPor>' || 'XML:ACP' || '</GeneradoPor>'); 
perform importacion.impxml_add(vNroXml, '</Encabezado>');
perform importacion.impxml_add(vNroXml, '<Renglones>');

LOOP
FETCH cAsiento INTO vIdCtb, vCodCtb, vNombreCtb, vSigno, vImpo;
EXIT WHEN (NOT FOUND);

IF vSigno = 1 THEN
perform importacion.impxml_add(vNroXml, '<RenglonContable Signo = ''Entrada''>');
ELSE
perform importacion.impxml_add(vNroXml, '<RenglonContable Signo = ''Salida''>');
END IF;

perform importacion.impxml_add(vNroXml, '<IdCtb>' || VidCtb || '</IdCtb>'); 
perform importacion.impxml_add(vNroXml, '<Impo>' || vImpo || '</Impo>'); 
perform importacion.impxml_add(vNroXml, '</RenglonContable>');
END LOOP;

perform importacion.impxml_add(vNroXml, '</Renglones>');
perform importacion.impxml_add(vNroXml, '</Comprobante>');
CLOSE cAsiento;

perform importacion.impxml_add(vNroXml, '</Movimientos>');

--Retornar el nroXML del xml generado
RETURN vNroXml;
END;$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION generar_asiento_apertura(character varying, timestamp without time zone)  OWNER TO abacouser;

-------------------------------------------------------------------------------------------------------------

-- Function: generar_asiento_cierre(character varying, character varying, timestamp without time zone, timestamp without time zone)
-- DROP FUNCTION generar_asiento_cierre(character varying, character varying, timestamp without time zone, timestamp without time zone);

CREATE OR REPLACE FUNCTION generar_asiento_cierre(character varying, character varying, timestamp without time zone, timestamp without time zone)
  RETURNS integer AS
$BODY$

DECLARE

pCodAmbEmp      alias for $1;
pSysUniSuc      alias for $2;
pFechaIni       alias for $3;
pFechaFin       alias for $4;
cAsiento        REFCURSOR;
vIdCtb		integer;
vCodCtb		varchar(20);
vNombreCtb      varchar(100);
vSigno		integer;
vImpo		numeric(16,2);
vAsientoCierreTipoCom	  com.tipo%TYPE;
vCodCtbrCuentasResultado  ctbr.cod%TYPE;
vIdCtbResultadoEjercicio  integer;
vImpoResultadoEjercicio       numeric(16,2);
vNroXml         INTEGER;

BEGIN

-- Primero verifico que esten todos los parametros que requiere el cierre contable.
select ctbcfg.asientocierretipocom into vAsientoCierreTipoCom
from ctbcfg
join com on ctbcfg.asientocierretipocom = com.tipo;

IF vAsientoCierreTipoCom is null THEN raise exception 'Primero debe configurar en la opcion Parametros Contables el comprobante de Cierre Contable';
END IF;

select ctbcfg.codctbrcuentasresultado into vCodCtbrCuentasResultado
from ctbcfg limit 1;

IF vCodCtbrCuentasResultado is null THEN raise exception 'Primero debe configurar en la opcion Parametros Contables el rubro Cuentas de Resultado';
END IF;

select ctbcfg.idctbresultadoejercicio into vIdCtbResultadoEjercicio
from ctbcfg limit 1;

IF vIdCtbResultadoEjercicio is null THEN raise exception 'Primero debe configurar en la opcion Parametros Contables la cuenta donde se imputa el Resultado del Ejercicio';
END IF;

-- Obtencion del numero de importacion.
vNroXml:= ( SELECT NEXTVAL('importacion.sec_next_nroxml') );

-- Generacion del xml
perform importacion.impxml_add(vNroXml, '<Movimientos>');

-- 1) Cierre de las cuentas de Resultado
-- Obtengo el importe resultado del ejercicio
select sum(commov.impo * commov.signo) into vImpoResultadoEjercicio
from commov
join comm on commov.idcomm = comm.id
join ambempsuc on comm.codambsuc = ambempsuc.codambsuc
join ctb on commov.idctb = ctb.id
where ambempsuc.codambemp = pCodAmbEmp and
index(pSysUniSuc ,comm.codambsuc) > 0 and
ctb.cod >= vCodCtbrCuentasResultado and
comm.fecha between pFechaIni and pFechaFin;

-- Query para el asiento de cierre de resultado
open cAsiento FOR
(
SELECT ctb.id as idctb, ctb.cod as codctb, ctb.nombre as nombrectb, 
case when x.impo < 0 then -1 else 1 end as signo, abs(x.impo) as impo
FROM

(
select ctb.id as idctb, -1 * sum(commov.impo * commov.signo) as impo
from commov
join comm on commov.idcomm = comm.id
join ambempsuc on comm.codambsuc = ambempsuc.codambsuc
join ctb on commov.idctb = ctb.id
where ambempsuc.codambemp = pCodAmbEmp and
index(pSysUniSuc ,comm.codambsuc) > 0 and
ctb.cod >= vCodCtbrCuentasResultado and
comm.fecha between pFechaIni and pFechaFin
group by 1

UNION ALL

select vIdCtbResultadoEjercicio as idctb, vImpoResultadoEjercicio as impo

) x

join ctb on x.idctb = ctb.id
where x.impo <> 0.00
order by signo desc, ctb.cod
);

-- Aqui se genera el comprobante.
perform importacion.impxml_add(vNroXml, '<Comprobante TipoCom = ''' || vAsientoCierreTipoCom || '''>');
perform importacion.impxml_add(vNroXml, '<Encabezado>');
perform importacion.impxml_add(vNroXml, '<Fecha>' || to_char(cast(pFechaFin as date), 'DD/MM/YYYY') || '</Fecha>'); 
perform importacion.impxml_add(vNroXml, '<Detalle>' || 'Cierre de las Cuentas de Resultado' || '</Detalle>'); 
perform importacion.impxml_add(vNroXml, '<GeneradoPor>' || 'XML:CCR' || '</GeneradoPor>'); 
perform importacion.impxml_add(vNroXml, '</Encabezado>');
perform importacion.impxml_add(vNroXml, '<Renglones>');

LOOP
FETCH cAsiento INTO vIdCtb, vCodCtb, vNombreCtb, vSigno, vImpo;
EXIT WHEN (NOT FOUND);

IF vSigno = 1 THEN
perform importacion.impxml_add(vNroXml, '<RenglonContable Signo = ''Entrada''>');
ELSE
perform importacion.impxml_add(vNroXml, '<RenglonContable Signo = ''Salida''>');
END IF;

perform importacion.impxml_add(vNroXml, '<IdCtb>' || VidCtb || '</IdCtb>'); 
perform importacion.impxml_add(vNroXml, '<Impo>' || vImpo || '</Impo>'); 
perform importacion.impxml_add(vNroXml, '</RenglonContable>');
END LOOP;

perform importacion.impxml_add(vNroXml, '</Renglones>');
perform importacion.impxml_add(vNroXml, '</Comprobante>');
CLOSE cAsiento;

-- 2) Cierre de las cuentas de Activo, Pasivo y Patrimonio Neto.
open cAsiento FOR
(
SELECT ctb.id as idctb, ctb.cod as codctb, ctb.nombre as nombrectb, 
case when x.impo < 0 then -1 else 1 end as signo, 
abs(x.impo) as impo
FROM

(
select ctb.id as idctb, -1 * sum(commov.impo * commov.signo) as impo
from commov
join comm on commov.idcomm = comm.id
join ambempsuc on comm.codambsuc = ambempsuc.codambsuc
join ctb on commov.idctb = ctb.id
where ambempsuc.codambemp = pCodAmbEmp and
index(pSysUniSuc ,comm.codambsuc) > 0 and
ctb.cod < vCodCtbrCuentasResultado and
comm.fecha between pFechaIni and pFechaFin
group by 1

UNION ALL

select vIdCtbResultadoEjercicio as idctb, -1 * vImpoResultadoEjercicio as impo
) x

join ctb on x.idctb = ctb.id
where x.impo <> 0.00
order by signo desc, ctb.cod
);

-- Aqui se genera el comprobante.
perform importacion.impxml_add(vNroXml, '<Comprobante TipoCom = ''' || vAsientoCierreTipoCom || '''>');
perform importacion.impxml_add(vNroXml, '<Encabezado>');
perform importacion.impxml_add(vNroXml, '<Fecha>' || to_char(cast(pFechaFin as date), 'DD/MM/YYYY') || '</Fecha>'); 
perform importacion.impxml_add(vNroXml, '<Detalle>' || 'Cierre de las Cuentas Patrimoniales' || '</Detalle>'); 
perform importacion.impxml_add(vNroXml, '<GeneradoPor>' || 'XML:CCP' || '</GeneradoPor>'); 
perform importacion.impxml_add(vNroXml, '</Encabezado>');
perform importacion.impxml_add(vNroXml, '<Renglones>');

LOOP
FETCH cAsiento INTO vIdCtb, vCodCtb, vNombreCtb, vSigno, vImpo;
EXIT WHEN (NOT FOUND);

IF vSigno = 1 THEN
perform importacion.impxml_add(vNroXml, '<RenglonContable Signo = ''Entrada''>');
ELSE
perform importacion.impxml_add(vNroXml, '<RenglonContable Signo = ''Salida''>');
END IF;

perform importacion.impxml_add(vNroXml, '<IdCtb>' || VidCtb || '</IdCtb>'); 
perform importacion.impxml_add(vNroXml, '<Impo>' || vImpo || '</Impo>'); 
perform importacion.impxml_add(vNroXml, '</RenglonContable>');
END LOOP;

perform importacion.impxml_add(vNroXml, '</Renglones>');
perform importacion.impxml_add(vNroXml, '</Comprobante>');

CLOSE cAsiento;

perform importacion.impxml_add(vNroXml, '</Movimientos>');

--Retornar el nroXML del xml generado

RETURN vNroXml;

END;$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION generar_asiento_cierre(character varying, character varying, timestamp without time zone, timestamp without time zone) OWNER TO abacouser;


-- ====================================
  SELECT aaVersion('465.02', '465.01');
-- ====================================